package com.jic.market.impl;

import com.beust.jcommander.internal.Sets;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.jic.common.base.vo.AdminOperate;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.common.base.vo.enums.DeptTypeEnums;
import com.jic.common.utils.IDUtils;
import com.jic.market.common.base.MarketBaseService;
import com.jic.market.common.enums.DeleteFlagEnum;
import com.jic.market.common.enums.MutexFlagEnum;
import com.jic.market.entity.*;
import com.jic.market.entity.mutex.MutexProductEntity;
import com.jic.market.entity.mutex.MutexResultContext;
import com.jic.market.enums.FrontPromTypeConditionTypeEnum;
import com.jic.market.enums.PromotionProductTypeEnum;
import com.jic.market.enums.PromotionStatusEnum;
import com.jic.market.enums.PromotionTypeEnum;
import com.jic.market.exception.BussinessException;
import com.jic.market.mapper.*;
import com.jic.market.mapper.base.BaseActivityMapper;
import com.jic.market.orm.Pagination;
import com.jic.market.request.*;
import com.jic.market.request.after.TellAddAllocationRequest;
import com.jic.market.response.PageResponse;
import com.jic.market.response.PromotionManagerResponse;
import com.jic.market.response.PromotionResponse;
import com.jic.market.response.PromotionRuleResponse;
import com.jic.market.service.JicMarketPromotionService;
import com.jic.market.service.PromotionMemberGradeService;
import com.jic.market.service.PromotionMutexService;
import com.jic.market.service.PromotionTemplateService;
import com.jic.market.service.allocation.AllocationLogicService;
import com.jic.market.service.mutex.MutexService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author admin
 * @version 1.0
 * @className JicMarketPromotionServiceImpl
 * @description JicMarketPromotionServiceImpl
 * @date 2020/1/10
 **/
@Service
public class JicMarketPromotionServiceImpl extends MarketBaseService implements JicMarketPromotionService {

    private final static Logger logger = LoggerFactory.getLogger(JicMarketPromotionServiceImpl.class);


    @Resource
    PromotionEntityMapper promotionEntityMapper;
    @Resource
    PromotionPresellRuleMapper promotionPresellRuleMapper;
    @Resource
    PromotionMerchantProductEntityMapper promotionMerchantProductEntityMapper;
    @Resource
    PromotionStoreProductEntityMapper promotionStoreProductEntityMapper;
    @Resource
    PromotionMerchantEntityMapper promotionMerchantEntityMapper;
    @Resource
    PromotionRuleEntityMapper promotionRuleEntityMapper;
    @Resource
    PromotionSingleProductRuleMapper promotionSingleProductRuleMapper;
    @Autowired
    private PromotionTemplateService promotionTemplateService;
    @Autowired
    private PromotionGiftItemEntityMapper promotionGiftItemEntityMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private AllocationLogicService allocationLogicService;
    @Autowired
    PromotionSingleRuleEntityMapper promotionSingleRuleEntityMapper;
    @Autowired
    PromotionLimitRuleEntityMapper promotionLimitRuleEntityMapper;
    @Autowired
    PromotionMutexService promotionMutexService;
    @Autowired
    MutexService mutexService;
    @Autowired
    PromotionMutexMapper promotionMutexMapper;
    @Resource
    private PatchGrouponThemeEntityMapper patchGrouponThemeEntityMapper;
    @Autowired
    private PromotionMemberGradeService promotionMemberGradeService;

    @Autowired
    private BaseActivityMapper baseActivityMapper;

    private static ExecutorService executorServiceR = Executors.newFixedThreadPool(20);

    @Override
    public PageResponse<PromotionResponse> listByPage(PromotionRequest request) {
        Pagination pagination = Pagination.build(request);
        PromotionEntity promotionEntity = new PromotionEntity();
        promotionEntity.setPromName(StringUtils.isNotBlank(request.getPromName()) ? request.getPromName() : null);
        promotionEntity.setStatus(request.getStatus());
        promotionEntity.setId(request.getId());
        promotionEntity.setPromotionCode(request.getPromotionCode());
        promotionEntity.setChannelCodes(StringUtils.isNotBlank(request.getChannelCode()) ? request.getChannelCode() : null);
        promotionEntity.setFrontPromType(request.getFrontPromType());
        //promotionEntity.setCreator(request.getCreator());
        promotionEntity.setStartTime(request.getStartTime());
        promotionEntity.setEndTime(request.getEndTime());
        promotionEntity.setDeleteFlag(0);
        promotionEntity.setPromType(request.getPromType());
        promotionEntity.setCreatorName(StringUtils.isNotBlank(request.getCreatorNameForSearch()) ? request.getCreatorNameForSearch() : null);
        promotionEntity.setDeptId(request.getAdminOperate().getDeptId());
        promotionEntity.setDeptType(request.getAdminOperate().getDeptType().getCode());
        promotionEntity.setBizId(request.getAdminOperate().getBusinessId());
        promotionEntity.setPromotionCode(StringUtils.isNotBlank(request.getPromotionCode()) ? request.getPromotionCode() : null);
        //Set<Long> promotionIds = getPromotionIdsByDeptType(request);
        // TODO
//        if(promotionIds == null){
//            return new PageResponse<PromotionResponse>()
//                    .setPageNo(request.getPageNo())
//                    .setPageSize(request.getPageSize())
//                    .setTotalCount(0);
//        }
//        promotionEntity.setIds(promotionIds);
        List<PromotionEntity> entityList = promotionEntityMapper.findOfPage(promotionEntity, pagination);
        int count = promotionEntityMapper.countOfPage(promotionEntity);
        PageResponse<PromotionResponse> responsePageResponse = new PageResponse<PromotionResponse>()
                .setPageNo(request.getPageNo())
                .setPageSize(request.getPageSize())
                .setTotalCount(count)
                .setList(entityList.stream().map(e -> {
                    PromotionResponse response = new PromotionResponse();
                    response.setId(e.getId())//活动id
                            .setPromType(e.getPromType())
                            .setPromName(e.getPromName())//活动名称
                            .setChannelCodes(e.getChannelCodes())//活动渠道["110001"]
                            .setEndTime(e.getEndTime())//开始时间
                            .setStartTime(e.getStartTime())//结束时间
                            .setFrontPromType(e.getFrontPromType())//活动类型
                            .setStatus(e.getStatus())//状态
                            .setCreatorName(e.getCreatorName())//创建人
                            .setCreateTime(e.getCreateTime())//创建时间
                            .setPromotionCode(e.getPromotionCode())
                            .setEditFlag(e.getDeptId().equals(request.getAdminOperate().getDeptId()) ? true : false)
                            .setAuditRemark(e.getAuditRemark());//审核备注
                    return response;
                }).collect(Collectors.toList()));
        return responsePageResponse;
    }

    /**
     * 根据deptType获取promotiondids,bizId(运营id,子平台id，或者merchantid,storeId)
     * @param request
     * @return
     */
    private Set<Long> getPromotionIdsByDeptType(PromotionRequest request) {
        Set<Long> promotionIds = new HashSet<>();
        DeptTypeEnums deptType = request.getAdminOperate().getDeptType();
        List<Long> merchantAll = null;
        List<Long> storeAll = null;
        List<Long> merchantIds = null;
        List<Long> storeIds = null;
        if(deptType != null){
            Long bizId = request.getAdminOperate().getBusinessId();
            //母平台
            if(deptType.equals(DeptTypeEnums.OPERATION_PLATFORM) || deptType.equals(DeptTypeEnums.CHILD_PLATFORM)){
                merchantIds = request.getAdminOperate().getMerchantIds();
                storeIds = request.getAdminOperate().getStoreIds();
            }else if(deptType.equals(DeptTypeEnums.MERCHANT_PLATFORM)){
                merchantIds = Arrays.asList(bizId);
                storeIds = request.getAdminOperate().getStoreIds();
            }else if(deptType.equals(DeptTypeEnums.STORE_PLATFORM)){
                storeIds = Arrays.asList(bizId);
            }
        }
        if(CollectionUtils.isNotEmpty(merchantIds)){
            merchantAll = promotionMerchantEntityMapper.findAllByMerchantIds(merchantIds);
            if(CollectionUtils.isNotEmpty(merchantAll)){
                promotionIds.addAll(merchantAll);
            }
        }
        if(CollectionUtils.isNotEmpty(storeIds)){
            storeAll = promotionMerchantEntityMapper.findAllByStoreIds(storeIds);
            if(CollectionUtils.isNotEmpty(storeAll)){
                promotionIds.addAll(storeAll);
            }
        }
        return CollectionUtils.isEmpty(promotionIds) ? null : promotionIds;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public PromotionResponse addPromotion(PromotionRequest request) {
        PromotionEntity promotionEntity = this.savePromotion(request);

        PromotionResponse response = new PromotionResponse();
        BeanUtils.copyProperties(promotionEntity, response);
        List<PromotionRuleRequest.PromotionRuleListRequest> promotionRules = request.getPromotionRules();
        if (CollectionUtils.isNotEmpty(promotionRules)) {
            promotionRules.forEach(x -> {
                FrontPromTypeConditionTypeEnum frontPromTypeConditionTypeEnum = FrontPromTypeConditionTypeEnum.lookByFrontType(request.getFrontPromType());
                if (frontPromTypeConditionTypeEnum != null) {
                    //保存promotion_rule数据
                    PromotionRuleEntity ruleEntity = new PromotionRuleEntity();
                    ruleEntity.setPromotionId(promotionEntity.getId());
                    ruleEntity.setConditionType(frontPromTypeConditionTypeEnum.getConditionType());
                    ruleEntity.setConditionValue(x.getConditionValue() != null ? x.getConditionValue().multiply(frontPromTypeConditionTypeEnum.getConditionMultiply()).longValue() : null);
                    ruleEntity.setContentValue(x.getContentValue() != null ? x.getContentValue().multiply(frontPromTypeConditionTypeEnum.getContentValueMultiply()) : null);
                    ruleEntity.setContentType(request.getFrontPromType());
                    ruleEntity.setLevel(promotionRules.indexOf(x));
                    promotionRuleEntityMapper.insert(ruleEntity);
                }
            });
        }

//        MemberGradeInfoRequest memberGradeInfoRequest = new MemberGradeInfoRequest();
//        memberGradeInfoRequest.setPromotionId(promotionEntity.getId().toString());
//        memberGradeInfoRequest.setPromotionCode(promotionEntity.getPromotionCode());
//        memberGradeInfoRequest.setPromType(promotionEntity.getPromType());
//        memberGradeInfoRequest.setFrontPromType(promotionEntity.getFrontPromType());
//        memberGradeInfoRequest.setPromotionMemberGradeList(request.getPromotionMemberGradeList());
//        promotionMemberGradeService.addMemberGrade(memberGradeInfoRequest);

        return response;

    }

    @Override
    public PromotionResponse detail(PromotionRequest request) {
        Long id = request.getId();
        PromotionResponse response = new PromotionResponse();
        PromotionEntity promotionEntity = promotionEntityMapper.queryById(id);
        BeanUtils.copyProperties(promotionEntity, response);
        if(request.getAdminOperate() != null){
            response.setEditFlag(promotionEntity.getDeptId().equals(request.getAdminOperate().getDeptId()) ? true : false);
        }
        //预售活动
        PromotionPresellRule presellRule = new PromotionPresellRule();
        presellRule.setPromotionId(id);
        List<PromotionPresellRule> presellRuleList = promotionPresellRuleMapper.query(presellRule);
        if(null != presellRuleList && !presellRuleList.isEmpty()){
            BeanUtils.copyProperties(presellRuleList.get(0), response, "id");
        }

        response.setChannelCodes(promotionEntity.getChannelCodes());
        PromotionRuleEntity ruleEntity = new PromotionRuleEntity();
        if(!promotionEntity.getPromType().equals(PromotionTypeEnum.PAYMENT_REDUCTION.getCode())){
            ruleEntity.setContentType(promotionEntity.getFrontPromType());
        }
        ruleEntity.setPromotionId(id);
        ruleEntity.setDeleteFlag(0);
        List<PromotionRuleEntity> ruleEntities = promotionRuleEntityMapper.findAll(ruleEntity);
        List<PromotionRuleResponse> collect = ruleEntities.stream().map(x -> {
            FrontPromTypeConditionTypeEnum frontPromTypeConditionTypeEnum = FrontPromTypeConditionTypeEnum.lookByFrontType(promotionEntity.getFrontPromType());
            PromotionRuleResponse ruleResponse = new PromotionRuleResponse();
            BeanUtils.copyProperties(x, ruleResponse);
            if(frontPromTypeConditionTypeEnum!=null){

                ruleResponse.setConditionValue(x.getConditionValue() != null ? new BigDecimal(x.getConditionValue()).divide(frontPromTypeConditionTypeEnum.getConditionMultiply()) : null);
                ruleResponse.setContentValue(x.getContentValue() != null ? x.getContentValue().divide(frontPromTypeConditionTypeEnum.getContentValueMultiply()) : null);
            }else if(response.getPromType().equals(PromotionTypeEnum.PAYMENT_REDUCTION.getCode())){
                FrontPromTypeConditionTypeEnum payFrontPromType = FrontPromTypeConditionTypeEnum.lookByFrontType(x.getConditionType());
                ruleResponse.setConditionValue(x.getConditionValue() != null ? new BigDecimal(x.getConditionValue()).divide(payFrontPromType.getConditionMultiply()) : null);
                ruleResponse.setContentValue(x.getContentValue() != null ? x.getContentValue().divide(payFrontPromType.getContentValueMultiply()) : null);
            }
            return ruleResponse;
        }).collect(Collectors.toList());
        response.setPromotionRules(collect);
        //获取tagName
//        if(promotionEntity.getLabel() != null){
//            Tag tag = tagMapper.queryByPrimaryKey(Long.valueOf(promotionEntity.getLabel()));
//            if(tag != null){
//                response.setTagName(tag.getTagName());
//            }
//        }

//        List<PromotionMemberGradeRequest> promotionMemberGradeRequestList = promotionMemberGradeService.queryMemberGrade(String.valueOf(promotionEntity.getId()));
//        response.setPromotionMemberGradeList(promotionMemberGradeRequestList);

        return response;
    }

    @Override
    public PromotionEntity queryEntity(String promotionCode) {
        PromotionEntity promotionEntity = promotionEntityMapper.queryByPromotionCode(promotionCode);
        return promotionEntity;
    }

    @Override
    public void delete(Long id) {
        PromotionEntity promotionEntity = new PromotionEntity();
        promotionEntity.setId(id);
        promotionEntity.setDeleteFlag(1);
        promotionEntityMapper.update(promotionEntity);
        //删除规则
        promotionRuleEntityMapper.deleteByPromotionId(id);
        //删除商品
        promotionMerchantProductEntityMapper.deleteEntityByPromotionId(id);
        //删除互斥
        promotionMutexService.deleteByPromotionIdAndPromType(id, promotionEntityMapper.queryById(id).getPromType());
        //删除赠品
        promotionGiftItemEntityMapper.deletGiftItemByPromotionId(id);
    }

    @Override
    public int update(PromotionRequest param) {
        PromotionEntity promotionEntity = new PromotionEntity();
        BeanUtils.copyProperties(param, promotionEntity);
        return promotionEntityMapper.update(promotionEntity);
    }

    @Override
    public Long copy(Long id) {
        PromotionEntity byId = promotionEntityMapper.queryById(id);
        byId.setId(null);
        byId.setStatus(1);
        byId.setPromName(byId.getPromName() + "-复制");
        byId.setCreateTime(new Date());
        promotionEntityMapper.insert(byId);
        return byId.getId();
    }

    @Override
    public int updateStatus(PromotionRequest request) {
        PromotionEntity promotionEntity = new PromotionEntity();
        promotionEntity.setId(request.getId());
        promotionEntity.setStatus(request.getStatus());
        promotionEntity.setAuditRemark(request.getAuditRemark());
        if(request.getStatus() != null && request.getStatus() == 11){//审核
            TellAddAllocationRequest tellAddAllocationRequest = new TellAddAllocationRequest();
            tellAddAllocationRequest.setPromotionId(request.getId() + "");
            tellAddAllocationRequest.setPromType(promotionEntityMapper.queryById(request.getId()).getPromType());
            allocationLogicService.addAllocation(tellAddAllocationRequest);
        }
        return promotionEntityMapper.update(promotionEntity);
    }

    @Override
    public RestResult reviewPromotion(PromotionRequest request) {
        // 复制主表
        PromotionEntity promotionEntityQ = new PromotionEntity();
        promotionEntityQ.setId(request.getId());
//        PromotionEntity promotionEntity = promotionEntityMapper.query(promotionEntityQ);
//        PromotionMerchantEntity promotionMerchantEntity = new PromotionMerchantEntity();
//        promotionMerchantEntity.setPromotionId(request.getId());
//        promotionMerchantEntity.setMerchantType(1);
//        promotionMerchantEntity.setDeleteFlag(0);
//        int merchantListCount = promotionMerchantEntityMapper.countOfPage(promotionMerchantEntity);
//        promotionMerchantEntity.setMerchantType(2);
//        int storeListCount = promotionMerchantEntityMapper.countOfPage(promotionMerchantEntity);

        PromotionMerchantProductEntity promotionMerchantProductEntity = new PromotionMerchantProductEntity();
        promotionMerchantProductEntity.setPromotionId(request.getId());
        promotionMerchantProductEntity.setDeleteFlag(0);
        int productListCount = promotionMerchantProductEntityMapper.countOfPage(promotionMerchantProductEntity);
        if( productListCount<=0){
            return RestResult.error("0001","商品信息不全，无法提交审核");
        }
        PromotionEntity updatePromotionStatus = new PromotionEntity();
        updatePromotionStatus.setId(request.getId());
        updatePromotionStatus.setStatus(request.getStatus());
        updatePromotionStatus.setAuditRemark(request.getAuditRemark());
        promotionEntityMapper.update(updatePromotionStatus);
        if(request.getStatus() != null && request.getStatus() == 11){//审核
            TellAddAllocationRequest tellAddAllocationRequest = new TellAddAllocationRequest();
            tellAddAllocationRequest.setPromotionId(request.getId() + "");
            tellAddAllocationRequest.setPromType(promotionEntityMapper.queryById(request.getId()).getPromType());
            allocationLogicService.addAllocation(tellAddAllocationRequest);
        }
        return RestResult.success("提交审核成功");
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long updatePromotion(PromotionRequest request) {
        PromotionEntity promotionEntity = new PromotionEntity();
        BeanUtils.copyProperties(request,promotionEntity);
        if (null != request.getChannelCodes() && !request.getChannelCodes().isEmpty()) {
            promotionEntity.setChannelCodes(request.getChannelCodes());
        }
        if (null != request.getProPlatform() && !request.getProPlatform().isEmpty()) {
            promotionEntity.setPromotionId(Joiner.on("|").join(request.getProPlatform()));
        }
        if (null != request.getProUserType() && !request.getProUserType().isEmpty()) {
            promotionEntity.setProUserType(Joiner.on("|").join(request.getProUserType()));
        }
        if (null != request.getProMemberType() && !request.getProMemberType().isEmpty()) {
            promotionEntity.setProMemberType(Joiner.on("|").join(request.getProMemberType()));
        }
        if (null != request.getProMemberLevel() && !request.getProMemberLevel().isEmpty()) {
            promotionEntity.setProMemberLevel(Joiner.on("|").join(request.getProMemberLevel()));
        }
        promotionEntityMapper.update(promotionEntity);

        //单品X件、赠送、换购编辑时重新校验互斥
       /* if(PromotionTypeEnum.XOFFER.getCode().equals(promotionEntity.getPromType())
            || PromotionTypeEnum.GIFT.getCode().equals(promotionEntity.getPromType())
            || PromotionTypeEnum.increase.getCode().equals(promotionEntity.getPromType())
        ){*/
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    updatePromotionMutex(promotionEntity,request);
                }
            });
            t.start();
//        }


        //预售活动数据
        PromotionPresellRule presellRuleQ = new PromotionPresellRule();
        presellRuleQ.setPromotionId(request.getId());
        List<PromotionPresellRule> presellRuleList = promotionPresellRuleMapper.query(presellRuleQ);
        if(null != presellRuleList && !presellRuleList.isEmpty()){
            PromotionPresellRule presellRule = new PromotionPresellRule();
            presellRule.setId(presellRuleList.get(0).getId());
            presellRule.setFrontPromMode(request.getFrontPromMode());
            presellRule.setFrontMoneyPayTimeStart(request.getFrontMoneyPayTimeStart());
            presellRule.setFrontMoneyPayTimeEnd(request.getFrontMoneyPayTimeEnd());
            presellRule.setTailMoneyPayTimeStart(request.getTailMoneyPayTimeStart());
            presellRule.setTailMoneyPayTimeEnd(request.getTailMoneyPayTimeEnd());
            presellRule.setSendGoodsTime(request.getSendGoodsTime());
            presellRule.setIsRefundFrontMoney(request.getIsRefundFrontMoney());
            presellRule.setUpdateTime(new Date());
            promotionPresellRuleMapper.update(presellRule);
        }

        List<PromotionRuleRequest.PromotionRuleListRequest> promotionRules = request.getPromotionRules();
        if (CollectionUtils.isNotEmpty(promotionRules)) {
            //先根据promotionId置为失效
            promotionRuleEntityMapper.deleteByPromotionId(promotionEntity.getId());
            promotionRules.forEach(x -> {
                FrontPromTypeConditionTypeEnum frontPromTypeConditionTypeEnum = FrontPromTypeConditionTypeEnum.lookByFrontType(request.getFrontPromType());
                if (frontPromTypeConditionTypeEnum != null || request.getPromType().equals(PromotionTypeEnum.PAYMENT_REDUCTION.getCode())) {
                    //保存promotion_rule数据
                    PromotionRuleEntity ruleEntity = new PromotionRuleEntity();
                    ruleEntity.setPromotionId(promotionEntity.getId());
                    if(frontPromTypeConditionTypeEnum!=null){
                        ruleEntity.setConditionType(frontPromTypeConditionTypeEnum.getConditionType());
                        ruleEntity.setConditionValue(x.getConditionValue() != null ? x.getConditionValue().multiply(frontPromTypeConditionTypeEnum.getConditionMultiply()).longValue() : null);
                        ruleEntity.setContentValue(x.getContentValue() != null ? x.getContentValue().multiply(frontPromTypeConditionTypeEnum.getContentValueMultiply()) : null);
                        ruleEntity.setContentType(request.getFrontPromType());
                    }else if(request.getPromType().equals(PromotionTypeEnum.PAYMENT_REDUCTION.getCode())){
                        FrontPromTypeConditionTypeEnum payFrontPromType = FrontPromTypeConditionTypeEnum.lookByFrontType(x.getConditionType());
                        ruleEntity.setConditionType(x.getConditionType());
                        ruleEntity.setConditionValue(x.getConditionValue() != null ? x.getConditionValue().multiply(payFrontPromType.getConditionMultiply()).longValue() : null);
                        ruleEntity.setContentValue(x.getContentValue() != null ? x.getContentValue().multiply(payFrontPromType.getContentValueMultiply()) : null);
                        ruleEntity.setContentType(x.getConditionType());
                    }

                    ruleEntity.setId(x.getId());
                    ruleEntity.setLevel(promotionRules.indexOf(x));
                    if (ruleEntity.getId() == null) {
                        promotionRuleEntityMapper.insert(ruleEntity);
                    } else {
                        ruleEntity.setDeleteFlag(0);
                        promotionRuleEntityMapper.update(ruleEntity);
                    }
                }
            });
        }
//        if(request.getStatus() != null && request.getStatus() == 11){//审核
//            TellAddAllocationRequest tellAddAllocationRequest = new TellAddAllocationRequest();
//            tellAddAllocationRequest.setPromotionId(request.getId() + "");
//            tellAddAllocationRequest.setPromType(promotionEntityMapper.queryById(request.getId()).getPromType());
//            allocationLogicService.addAllocation(tellAddAllocationRequest);
//        }

//        if(StringUtils.isNotBlank(request.getChannelCodes()) &&
//                null != request.getPromotionMemberGradeList() && !request.getPromotionMemberGradeList().isEmpty()){
//            MemberGradeInfoRequest memberGradeInfoRequest = new MemberGradeInfoRequest();
//            //查询活动
//            PromotionEntity promotionEntityInfo = promotionEntityMapper.queryById(promotionEntity.getId());
//            memberGradeInfoRequest.setPromotionId(promotionEntity.getId().toString());
//            memberGradeInfoRequest.setPromotionCode(promotionEntityInfo.getPromotionCode());
//            memberGradeInfoRequest.setPromType(promotionEntityInfo.getPromType());
//            memberGradeInfoRequest.setFrontPromType(promotionEntityInfo.getFrontPromType());
//            memberGradeInfoRequest.setPromotionMemberGradeList(request.getPromotionMemberGradeList());
//            promotionMemberGradeService.updateMemberGrade(memberGradeInfoRequest);
//        }
        return request.getId();
    }


    /**
     * 编辑时互斥校验
     * 单品X件、赠送、换购
     * @param promotionEntity
     * @param request
     */
    private void updatePromotionMutex(PromotionEntity promotionEntity, PromotionRequest request){
        PromotionMerchantProductEntity promotionMerchantProductEntity = new PromotionMerchantProductEntity();
        promotionMerchantProductEntity.setPromotionId(request.getId());
        promotionMerchantProductEntity.setDeleteFlag(0);
        promotionMerchantProductEntity.setMutexFlag(0);
        promotionMerchantProductEntity.setTypeOfProduct(PromotionProductTypeEnum.TYPE_SKU.getType());
        List<PromotionMerchantProductEntity> merchantProductEntities = promotionMerchantProductEntityMapper.findAll(promotionMerchantProductEntity);
        List<Long> productIds = merchantProductEntities.stream().map(PromotionMerchantProductEntity::getMpId).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(productIds)){
            final Set<Long> mutexList = Sets.newHashSet();
            MutexResultContext mutexResultContext = mutexService.doProcessMutex(promotionEntity.getId(), productIds);
            mutexList.addAll(mutexResultContext.getMutexList());
            final Map<Long, Long> mutexMpIdMap = Maps.newHashMap();
            //变更互斥FLAG
            merchantProductEntities.forEach(x->{
                x.setMutexFlag(mutexList.contains(x.getMpId()) ? MutexFlagEnum.MUTEX.getCode() : MutexFlagEnum.UN_MUTEX.getCode());
                x.setUpdateTime(new Date());
                x.setUpdator(request.getAdminOperate().getOperator());
                if(mutexList.contains(x.getMpId())){
                    mutexMpIdMap.put(x.getMpId(), x.getId());
                }
                x.setUpdatorName(request.getAdminOperate().getOperateName());
                promotionMerchantProductEntityMapper.update(x);
            });

            mutexResultContext.getMutexPromotionProducts().entrySet().forEach(e->{
                Set<MutexProductEntity> mutexProductEntitySet = e.getValue();
                promotionMutexService.deleteByPromotionProductId(mutexMpIdMap.get(e.getKey()));
                mutexProductEntitySet.forEach(m->{
                    promotionMutexService.insert(
                        new PromotionMutex()
                                .setPromotionId(m.getPromotionId())
                                .setPromType(m.getPromType())
                                .setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode())
                                .setPromotionMerchantProductId(mutexMpIdMap.get(e.getKey()))
                                .setCreator(request.getAdminOperate().getOperator())
                                .setCreatorName(request.getAdminOperate().getOperateName())
                    );
                });
            });
        }
    }

    @Override
    public List<PromotionEntity> queryPromotionListByIds(List<Long> idsList) {
        return promotionEntityMapper.queryPromotionListByIds(idsList);
    }

    /**
     * 添加单品X件优惠
     *
     * @param promotionRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PromotionResponse savePromotionSingleProduct(PromotionRequest promotionRequest) {
        //调用通用活动保存
        PromotionEntity promotionEntity = this.savePromotion(promotionRequest);

        PromotionResponse response = new PromotionResponse();
        BeanUtils.copyProperties(promotionEntity, response);
        List<PromotionSingleProductRuleRequest> promotionSingleProductRuleRequests = promotionRequest.getPromotionSingleProductRuleList();
        if (CollectionUtils.isNotEmpty(promotionSingleProductRuleRequests)) {
            promotionSingleProductRuleRequests.forEach(x -> {
                FrontPromTypeConditionTypeEnum frontPromTypeConditionTypeEnum = FrontPromTypeConditionTypeEnum.lookByFrontType(promotionRequest.getFrontPromType());
                if (frontPromTypeConditionTypeEnum != null) {
                    //保存第X件优惠促销活动规则
                    PromotionSingleProductRule ruleEntity = new PromotionSingleProductRule();
                    //保存创建登录相关
                    BeanUtils.copyProperties(promotionRequest, ruleEntity);
                    ruleEntity.setPromotionId(promotionEntity.getId());
                    ruleEntity.setFavourableCondition(x.getFavourableCondition());
                    ruleEntity.setFavourableContent(x.getFavourableContent());
                    promotionSingleProductRuleMapper.insertSelective(ruleEntity);
                }
            });

        }
        return response;
    }

    /**
     * 通用活动主表保存
     *
     * @param promotionRequest
     */
    protected PromotionEntity savePromotion(PromotionRequest promotionRequest) {
        PromotionEntity promotionEntity = new PromotionEntity();
        BeanUtils.copyProperties(promotionRequest, promotionEntity);
        AdminOperate adminOperate = promotionEntity.getAdminOperate();
        promotionEntity.setProPlatform("2");
        promotionEntity.setProMemberLevel("3");
        promotionEntity.setProMemberType("0");
        promotionEntity.setChannelCodes(promotionRequest.getChannelCodes());
        promotionEntity.setProUserType(Joiner.on("|").join(promotionRequest.getProUserType()));
        promotionEntity.setCreator(adminOperate.getOperator());
        promotionEntity.setCreatorName(adminOperate.getOperateName());
        promotionEntity.setUpdator(adminOperate.getOperator());
        promotionEntity.setUpdatorName(adminOperate.getOperateName());
        promotionEntity.setDeptId(adminOperate.getDeptId());
        promotionEntity.setPromotionCode(IDUtils.GenerateBillNo());
        promotionEntity.setDeptType(adminOperate.getDeptType().getCode());
        promotionEntityMapper.insert(promotionEntity);

        //预售活动数据
        if(null != promotionRequest.getSendGoodsTime()){
            PromotionPresellRule presellRule = new PromotionPresellRule();
            presellRule.setPromotionId(promotionEntity.getId());
            presellRule.setFrontPromMode(promotionRequest.getFrontPromMode());
            presellRule.setFrontMoneyPayTimeStart(promotionRequest.getFrontMoneyPayTimeStart());
            presellRule.setFrontMoneyPayTimeEnd(promotionRequest.getFrontMoneyPayTimeEnd());
            presellRule.setTailMoneyPayTimeStart(promotionRequest.getTailMoneyPayTimeStart());
            presellRule.setTailMoneyPayTimeEnd(promotionRequest.getTailMoneyPayTimeEnd());
            presellRule.setSendGoodsTime(promotionRequest.getSendGoodsTime());
            presellRule.setIsRefundFrontMoney(promotionRequest.getIsRefundFrontMoney());
            presellRule.setCreateTime(new Date());
            presellRule.setUpdateTime(new Date());
            presellRule.setDeleteFlag(false);
            presellRule.setCreator(adminOperate.getOperator());
            presellRule.setCreatorName(adminOperate.getOperateName());
            promotionPresellRuleMapper.insert(presellRule);
        }
        return promotionEntity;
    }


    /**
     * 查询单品X件优惠详情
     *
     * @param id
     * @return
     */
    @Override
    public PromotionManagerResponse queryPromotionDetail(Long id) {
        PromotionManagerResponse promotionManagerResponse=new PromotionManagerResponse();

        return promotionManagerResponse;
    }

    @Override
    public RestResult<Long> deepCopy(PromotionRequest request) {
        return executeQuery(() -> {
            // 复制配置信息，返回新的活动id
            PromotionTemplateService.CopyResult copyResult = copyConfig(request, PromotionStatusEnum.DRAFT, "-复制");
            if(null != copyResult){
                return Long.valueOf(copyResult.getPromotionId());
            }
            return null;
        });
    }

    @Override
    public RestResult<Long> saveTemplate(PromotionRequest request) {
        //判断名字是否重复
        PromotionEntity promotionEntity = new PromotionEntity();
        promotionEntity.setPromName(request.getTemplateName() + "-模板");
        promotionEntity.setStatus(10);
        int count = promotionEntityMapper.countOfTemplate(promotionEntity);
        if(count > 0){
            throw new BussinessException("-1", "模板名称重复");
        }
        return executeQuery(() -> {
            Long templateId = promotionTemplateService.saveTemplate(() -> {
                // 复制配置信息
                PromotionTemplateService.CopyResult copyResult = copyConfig(request, PromotionStatusEnum.TEMPLATE, "-模板");
                copyResult.setAdminOperate(request.getAdminOperate());

                return copyResult;
            });
            return templateId;
        });
    }

    // 单品x件活动删除
    @Override
    public RestResult<Long> delSingleProduct(PromotionRequest request) {
        return executeQuery(() ->{
                 PromotionEntity promotionEntity = new PromotionEntity();
                 promotionEntity.setId(request.getId());
                 promotionEntity.setDeleteFlag(1);
                 promotionEntity.setPromType(7);
                 long flag = promotionEntityMapper.update(promotionEntity);
                 return  flag;
        });
    }

   // 关闭单品X件促销活动
    @Override
    public RestResult<Long> closeXofferPromotion(PromotionRequest request) {
        return executeQuery(() ->{
            PromotionEntity promotionEntity = new PromotionEntity();
            promotionEntity.setStatus(7);
            promotionEntity.setId(request.getId());
            long flag = promotionEntityMapper.update(promotionEntity);
            return  flag;
        });
    }

    @Override
    public RestResult<PageResult<PromotionResponse>> queryPromotionList(QueryPromotionListRequest request){
        try {
            PageResult<PromotionResponse> rest = new PageResult<>();
            if (request.getStart() != null){
                request.setStart((request.getStart() - 1) * request.getLimit());
            }
            if(request.getPromType().equals(PromotionTypeEnum.GROUPON.getCode())){
                //查询拼团
                List<PromotionResponse> patchList = patchGrouponThemeEntityMapper.queryPromotionList(request);
                Long count = patchGrouponThemeEntityMapper.queryPromotionListCount(request);
                rest.setRows(patchList);
                rest.setTotal(count);
            }else{
                //查询通用
                List<PromotionResponse> promotionEntities = promotionEntityMapper.queryPromotionList(request);
                Long count = promotionEntityMapper.queryPromotionListCount(request);
                rest.setRows(promotionEntities);
                rest.setTotal(count);
            }
            return RestResult.success(rest);
        }catch (Exception e){
            logger.error("查询活动列表发生错误=====>>>>{}",e);
            return RestResult.error("9999","服务器发生错误,请重试");
        }
    }


                                                                          /**
     * 复制方法
     * @param request 被复制的活动
     * @param status 复制需要存储的状态
     * @param extenPromName 对应的活动扩展名
     * @return
     */
    private PromotionTemplateService.CopyResult copyConfig(PromotionRequest request, PromotionStatusEnum status, String extenPromName) {
        List<CompletableFuture<Integer>> completableFutures = new ArrayList<>();
        // 复制主表
        PromotionEntity promotionEntityQ = new PromotionEntity();
        promotionEntityQ.setId(request.getId());
        PromotionEntity promotionEntity = promotionEntityMapper.query(promotionEntityQ);
        //
        String oldPromotionCode = promotionEntity.getPromotionCode();

        if(null == promotionEntity) {
            return null;
        }
        promotionEntity.setPromotionCode(IDUtils.GenerateBillNo());
        promotionEntity.setId(null);
        promotionEntity.setStatus(status.getCode());
        promotionEntity.setPromName(promotionEntity.getPromName() + extenPromName);
        promotionEntity.setCreateTime(new Date());
        promotionEntity.setUpdateTime(new Date());
        int flag = promotionEntityMapper.insert(promotionEntity);
        if(0 == flag) {
            return null;
        }
        //结果组装
        PromotionTemplateService.CopyResult copyResult = new PromotionTemplateService.CopyResult();
        copyResult.setPromotionId(promotionEntity.getId() + "");
        copyResult.setPromType(PromotionTypeEnum.getByCode(promotionEntity.getPromType()));
        copyResult.setTemplateName(request.getTemplateName());

        CompletableFuture<Integer> ruleCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                // 复制规则配置表
                PromotionRuleEntity promotionRuleEntity = new PromotionRuleEntity();
                promotionRuleEntity.setPromotionId(request.getId());
                promotionRuleEntity.setDeleteFlag(0);
                List<PromotionRuleEntity> ruleEntities = promotionRuleEntityMapper.findAll(promotionRuleEntity);
                if(CollectionUtils.isNotEmpty(ruleEntities)){
                    ruleEntities.forEach(x->{
                        Long oldId = x.getId();
                        x.setId(null);
                        x.setCreateTime(null);
                        x.setUpdateTime(null);
                        x.setPromotionId(promotionEntity.getId());
                        promotionRuleEntityMapper.insert(x);
                        //查询promotion_gift_item数据
                        // 复制赠送配置表
                        if(promotionEntity.getPromType().equals(PromotionTypeEnum.GIFT.getCode()) || promotionEntity.getPromType().equals(PromotionTypeEnum.increase.getCode())){
                            PromotionGiftItemEntity promotionGiftItemEntity = new PromotionGiftItemEntity();
                            promotionGiftItemEntity.setPromotionId(request.getId());
                            promotionGiftItemEntity.setDeleteFlag(0);
                            promotionGiftItemEntity.setPromotionRuleId(oldId);
                            List<PromotionGiftItemEntity> promotionGiftItemEntities = promotionGiftItemEntityMapper.findAll(promotionGiftItemEntity);
                            if(CollectionUtils.isNotEmpty(promotionGiftItemEntities)){
                                promotionGiftItemEntities.forEach(i->{
                                    i.setPromotionRuleId(x.getId());
                                    i.setId(null);
                                    i.setCreateTime(null);
                                    i.setUpdateTime(null);
                                    i.setPromotionId(promotionEntity.getId());
                                    //promotionGiftItemEntityMapper.insert(i);
                                });
                                promotionGiftItemEntityMapper.insertBatch(promotionGiftItemEntities);
                            }
                        }
                    });
                }
                logger.info("copyConfig success promotionRule cost = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
               logger.error("copyConfig promotionRule error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(ruleCompletableFuture);


        CompletableFuture<Integer> presellCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                // 预售-复制规则配置表
                if(promotionEntity.getPromType().equals(PromotionTypeEnum.SINGLE.getCode())){
                    PromotionPresellRule promotionPresellRuleQ = new PromotionPresellRule();
                    promotionPresellRuleQ.setPromotionId(request.getId());
                    List<PromotionPresellRule> presellRuleList =  promotionPresellRuleMapper.query(promotionPresellRuleQ);
                    if(null != presellRuleList && !presellRuleList.isEmpty()){
                        presellRuleList.get(0).setPromotionId(promotionEntity.getId());
                        presellRuleList.get(0).setId(null);
                        promotionPresellRuleMapper.insert(presellRuleList.get(0));
                    }
                }
                logger.info("copyConfig success promotionPresellRule cost = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
                logger.error("copyConfig promotionPresellRule error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(presellCompletableFuture);



        CompletableFuture<Integer> merchantCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                // 复制商家店铺表
                PromotionMerchantEntity merchantEntityQ = new PromotionMerchantEntity();
                merchantEntityQ.setPromotionId(request.getId());
                merchantEntityQ.setDeleteFlag(0);
                List<PromotionMerchantEntity> promotionMerchantEntityList = promotionMerchantEntityMapper.findAll(merchantEntityQ);
                if(null != promotionMerchantEntityList && !promotionMerchantEntityList.isEmpty()){
                    for(PromotionMerchantEntity merchantEntity: promotionMerchantEntityList){
                        merchantEntity.setId(null);
                        merchantEntity.setPromotionId(promotionEntity.getId());
                        merchantEntity.setCreateTime(new Date());
                        merchantEntity.setUpdateTime(new Date());
                        //promotionMerchantEntityMapper.insert(merchantEntity);
                    }
                    promotionMerchantEntityMapper.insertBatch(promotionMerchantEntityList);
                }
                logger.info("copyConfig success promotionMerchant cost = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
                logger.error("copyConfig promotionMerchant error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(merchantCompletableFuture);


        CompletableFuture<Integer> merchantProductCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                //复制商家商品
                PromotionMerchantProductEntity promotionMerchantProductEntity = new PromotionMerchantProductEntity();
                promotionMerchantProductEntity.setPromotionId(request.getId());
                promotionMerchantProductEntity.setDeleteFlag(0);
                List<PromotionMerchantProductEntity> merchantProductEntities = promotionMerchantProductEntityMapper.findAll(promotionMerchantProductEntity);
                List<Long> productIds = merchantProductEntities.stream().filter(x->{return x.getTypeOfProduct().equals(PromotionProductTypeEnum.TYPE_SKU.getType());}).map(PromotionMerchantProductEntity::getMpId).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(merchantProductEntities)){
                    final Set<Long> mutexList = Sets.newHashSet();
                    final Map<Long, Long> mutexMpIdMap = Maps.newHashMap();
                    Map<Long, Set<MutexProductEntity>> mutexPromotionProducts = null;
                    if(status.equals(PromotionStatusEnum.DRAFT)){
                        MutexResultContext mutexResultContext = mutexService.doProcessMutex(promotionEntity.getId(), productIds);
                        mutexList.addAll(mutexResultContext.getMutexList());
                        mutexPromotionProducts = mutexResultContext.getMutexPromotionProducts();
                    }
                    merchantProductEntities.forEach(x->{
                        //复制需要计算互斥逻辑
                        x.setMutexFlag(mutexList.contains(x.getMpId()) ? MutexFlagEnum.MUTEX.getCode() : MutexFlagEnum.UN_MUTEX.getCode());
                        x.setId(null);
                        x.setPromotionId(promotionEntity.getId());
                        x.setCreateTime(null);
                        x.setUpdateTime(null);
                    });
                    promotionMerchantProductEntityMapper.insertBatchNew(merchantProductEntities);

                    merchantProductEntities.forEach(x->{
                        if(mutexList.contains(x.getMpId())){
                            mutexMpIdMap.put(x.getMpId(), x.getId());
                        }
                    });

                    if(mutexPromotionProducts != null){
                        mutexPromotionProducts.entrySet().forEach(e->{
                            Set<MutexProductEntity> mutexProductEntitySet = e.getValue();
                            promotionMutexService.deleteByPromotionProductId(mutexMpIdMap.get(e.getKey()));
                            List<PromotionMutex> collect = mutexProductEntitySet.stream().map(m -> {
                                return new PromotionMutex()
                                        .setPromotionId(m.getPromotionId())
                                        .setPromType(m.getPromType())
                                        .setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode())
                                        .setPromotionMerchantProductId(mutexMpIdMap.get(e.getKey()))
                                        .setCreator(request.getCreator())
                                        .setCreatorName(request.getCreatorName())
                                        .setCreateTime(new Date())
                                        .setUpdator(request.getUpdator())
                                        .setUpdatorName(request.getUpdatorName());
                            }).collect(Collectors.toList());
                            promotionMutexService.insertBatch(collect);
                        });
                    }
                }
                logger.info("copyConfig success promotionMerchantProduct = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
                logger.error("copyConfig  promotionMerchantProduct error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(merchantProductCompletableFuture);


        CompletableFuture<Integer> limitRuleCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                //复制promotion_limit_rule表
                PromotionLimitRuleEntity promotionLimitRuleEntity = new PromotionLimitRuleEntity();
                promotionLimitRuleEntity.setPromotionId(request.getId());
                promotionLimitRuleEntity.setDeleteFlag(0);
                List<PromotionLimitRuleEntity> limitRuleEntities = promotionLimitRuleEntityMapper.findAll(promotionLimitRuleEntity);
                if(CollectionUtils.isNotEmpty(limitRuleEntities)){
                    limitRuleEntities.forEach(x->{
                        x.setId(null);
                        x.setPromotionId(promotionEntity.getId());
                        x.setCreateTime(null);
                        x.setUpdateTime(null);
                        //promotionLimitRuleEntityMapper.insert(x);
                    });
                    promotionLimitRuleEntityMapper.insertBatch(limitRuleEntities);
                }
                logger.info("copyConfig success promotionLimitRule cost = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
                logger.error("copyConfig promotionLimitRule error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(limitRuleCompletableFuture);



        //复制promotion_single_rule表
       if(promotionEntity.getPromType().equals(PromotionTypeEnum.SINGLELY.getCode())){
           CompletableFuture<Integer> singleLimitRuleCompletableFuture = CompletableFuture.supplyAsync(() -> {
               try {
                   long start = System.currentTimeMillis();
                   PromotionSingleRuleEntity param = new PromotionSingleRuleEntity();
                   param.setPromotionId(request.getId());
                   param.setDeleteFlag(0);
                   List<PromotionSingleRuleEntity> promotionSingleRuleEntityList = promotionSingleRuleEntityMapper.findAll(param);
                   if(CollectionUtils.isNotEmpty(promotionSingleRuleEntityList)){
                       promotionSingleRuleEntityList.forEach(x->{
                           x.setId(null);
                           x.setPromotionId(promotionEntity.getId());
                           x.setCreateTime(null);
                           x.setUpdateTime(null);
                           //promotionSingleRuleEntityMapper.insert(x);
                       });
                       promotionSingleRuleEntityMapper.insertBatch(promotionSingleRuleEntityList);
                   }
                   logger.info("copyConfig success promotionSingleRule cost = {}", System.currentTimeMillis() - start);
               } catch (Exception e) {
                   logger.error("copyConfig promotionSingleRule error", e);
               }
               return 1;
           }, executorServiceR);
           completableFutures.add(singleLimitRuleCompletableFuture);
       }

        CompletableFuture<Integer> memberGradeRuleCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                long start = System.currentTimeMillis();
                promotionMemberGradeService.copyMemberGrade(oldPromotionCode, promotionEntity.getId().toString(), promotionEntity.getPromotionCode());
                logger.info("copyConfig success copyMemberGrade cost = {}", System.currentTimeMillis() - start);
            } catch (Exception e) {
                logger.error("copyConfig copyMemberGrade error", e);
            }
            return 1;
        }, executorServiceR);
        completableFutures.add(memberGradeRuleCompletableFuture);
        CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()])).join();

        // TODO 根据自己活动规则复制相应的表
        return copyResult;
    }
}
